import 'dart:convert';

import 'package:flutter/cupertino.dart';
import 'package:flutter_openim_sdk/flutter_openim_sdk.dart';
import 'package:get/get.dart';
import 'package:openim/pages/chat/chat_logic.dart';
import 'package:openim_common/openim_common.dart';
import 'package:rxdart/rxdart.dart';

import 'controller/app_controller.dart';
import 'controller/im_controller.dart';

enum IMSdkStatus {
  connectionFailed,
  connecting,
  connectionSucceeded,
  syncStart,
  synchronizing,
  syncEnded,
  syncFailed,
  syncProgress,
}

enum KickoffType {
  kickedOffline,
  userTokenInvalid,
  userTokenExpired,
}

mixin IMCallback {
  final initLogic = Get.find<AppController>();

  // 添加 imLogic getter
  IMController get imLogic => Get.find<IMController>();

  Function(RevokedInfo info)? onRecvMessageRevoked;

  Function(List<ReadReceiptInfo> list)? onRecvC2CReadReceipt;

  Function(Message msg)? onRecvNewMessage;

  Function(Message msg)? onRecvOfflineMessage;

  Function(String msgId, int progress)? onMsgSendProgress;

  Function(BlacklistInfo u)? onBlacklistAdd;

  Function(BlacklistInfo u)? onBlacklistDeleted;

  Function(int current, int size)? onUploadProgress;

  final conversationAddedSubject = BehaviorSubject<List<ConversationInfo>>();

  final conversationChangedSubject = BehaviorSubject<List<ConversationInfo>>();

  final unreadMsgCountEventSubject = PublishSubject<int>();

  final friendApplicationChangedSubject = BehaviorSubject<FriendApplicationInfo>();

  final friendAddSubject = BehaviorSubject<FriendInfo>();

  final friendDelSubject = BehaviorSubject<FriendInfo>();

  final friendInfoChangedSubject = PublishSubject<FriendInfo>();

  final selfInfoUpdatedSubject = BehaviorSubject<UserInfo>();

  final userStatusChangedSubject = BehaviorSubject<UserStatusInfo>();

  final groupInfoUpdatedSubject = BehaviorSubject<GroupInfo>();

  final groupApplicationChangedSubject = BehaviorSubject<GroupApplicationInfo>();

  final initializedSubject = PublishSubject<bool>();

  final memberAddedSubject = BehaviorSubject<GroupMembersInfo>();

  final memberDeletedSubject = BehaviorSubject<GroupMembersInfo>();

  final memberInfoChangedSubject = PublishSubject<GroupMembersInfo>();

  final joinedGroupDeletedSubject = BehaviorSubject<GroupInfo>();

  final joinedGroupAddedSubject = BehaviorSubject<GroupInfo>();

  final onKickedOfflineSubject = PublishSubject<KickoffType>();

  final imSdkStatusSubject = ReplaySubject<({IMSdkStatus status, bool reInstall, int? progress})>();

  final imSdkStatusPublishSubject = PublishSubject<({IMSdkStatus status, bool reInstall, int? progress})>();

  final inputStateChangedSubject = PublishSubject<InputStatusChangedData>();

  void imSdkStatus(IMSdkStatus status, {bool reInstall = false, int? progress}) {
    imSdkStatusSubject.add((status: status, reInstall: reInstall, progress: progress));
    imSdkStatusPublishSubject.add((status: status, reInstall: reInstall, progress: progress));
  }

  void kickedOffline() {
    onKickedOfflineSubject.add(KickoffType.kickedOffline);
  }

  void userTokenInvalid() {
    onKickedOfflineSubject.add(KickoffType.userTokenInvalid);
  }

  void selfInfoUpdated(UserInfo u) {
    selfInfoUpdatedSubject.addSafely(u);
  }

  void userStausChanged(UserStatusInfo u) {
    userStatusChangedSubject.addSafely(u);
  }

  void uploadLogsProgress(int current, int size) {
    onUploadProgress?.call(current, size);
  }

  void recvMessageRevoked(RevokedInfo info) {
    onRecvMessageRevoked?.call(info);
  }

  void recvC2CMessageReadReceipt(List<ReadReceiptInfo> list) {
    onRecvC2CReadReceipt?.call(list);
  }

   Future<void> recvNewMessage(Message msg) async {
      // 检查是否为自动回复的通话拦截消息
    if (msg.isCustomType && _isAutoReplyCallBlockedMessage(msg)) {
      debugPrint("收到自动回复通话拦截消息: $msg");
      _handleAutoReplyCallBlockedMessage(msg);
      // 自动回复消息被拦截，调整未读计数
      await _adjustUnreadCountForBlockedMessage(msg);
      return;
    }
    debugPrint("收到新消息: $msg");
    // 检查是否为自动回复的好友关系异常消息
    if (msg.isCustomType && _isAutoReplyDeletedMessage(msg)) {
      debugPrint("_handleAutoReplyDeletedMessage");
      _handleAutoReplyDeletedMessage(msg);
      // 自动回复消息被拦截，调整未读计数
      await _adjustUnreadCountForBlockedMessage(msg);
      return;
    }
    
 
    
    // 全局拦截：检查是否为单聊且需要验证好友关系
    if (msg.sessionType == ConversationType.single && msg.sendID != OpenIM.iMManager.userID) {
      _checkFriendshipAndFilter(msg);
      return;
    }
    
  
    
    // 处理通话相关的自定义消息
    if (msg.isCustomType) {
      try {
        final data = msg.customElem!.data;
        if (data != null) {
          final map = jsonDecode(data);
          final customType = map['customType'];
          if (customType == CustomMessageType.callingInvite ||
              customType == CustomMessageType.callingAccept ||
              customType == CustomMessageType.callingReject ||
              customType == CustomMessageType.callingCancel ||
              customType == CustomMessageType.callingHungup) {
            imLogic.processCallMessage(msg);
            return;
          }
        }
      } catch (e) {
        Logger.print('处理通话消息失败: $e');
      }
    }
    
    initLogic.showNotification(msg);
    onRecvNewMessage?.call(msg);
  }

  /// 调整被拦截消息的未读计数
  Future<void> _adjustUnreadCountForBlockedMessage(Message msg) async {
    try {
      // 获取当前总未读消息数
      final currentCount = await OpenIM.iMManager.conversationManager.getTotalUnreadMsgCount();
      final currentCountInt = int.tryParse(currentCount) ?? 0;
      
      // 如果当前计数大于0，则减1（因为被拦截的消息不应该计入未读数）
      if (currentCountInt > 0) {
        final adjustedCount = currentCountInt - 1;
        Logger.print('调整未读消息计数：从 $currentCountInt 调整为 $adjustedCount（消息被拦截）');
        
        // 手动触发未读消息计数更新
        totalUnreadMsgCountChanged(adjustedCount);
      }
    } catch (e) {
      Logger.print('调整被拦截消息的未读计数失败: $e');
    }
  }

  // 检查好友关系并过滤消息
  void _checkFriendshipAndFilter(Message msg) async {
    try {
      debugPrint("全局拦截检查好友关系: ${msg.sendID}");
      // 获取好友信息来验证是否为好友
      final friendsInfo = await OpenIM.iMManager.friendshipManager.getFriendsInfo(
        userIDList: [msg.sendID!],
      );
      
      // 如果获取不到好友信息或列表为空，说明不是好友，拒绝接收并发送提醒
      if (friendsInfo.isEmpty) {
        Logger.print('全局拦截：拒绝接收陌生人消息: ${msg.sendID}');
        
        // 发送"你已被对方删除"的提醒消息给发送方
        await _sendDeletedByFriendNotification(msg.sendID!);
        
        // 消息被拦截，手动调整未读消息计数
        await _adjustUnreadCountForBlockedMessage(msg);
        return;
      }
      
      // 是好友，继续正常处理消息
      debugPrint("是好友，继续处理消息: ${msg.sendID}");
      _processNormalMessage(msg);
      
    } catch (e) {
      // 如果获取好友信息失败，也拒绝接收消息
      Logger.print('全局拦截：获取好友信息失败，拒绝接收消息: ${msg.sendID}, error: $e');
      
      // 消息被拦截，手动调整未读消息计数
      await _adjustUnreadCountForBlockedMessage(msg);
      return;
    }
  }

  // 发送"你已被对方删除"的提醒消息
  Future<void> _sendDeletedByFriendNotification(String targetUserID) async {
    try {
      // 创建自定义消息，告知对方已被删除
      final notificationMessage = await OpenIM.iMManager.messageManager.createCustomMessage(
        data: json.encode({
          'customType': CustomMessageType.deletedByFriend,
          'data': {
            'tips': '你已被对方删除，无法发送消息',
            'isAutoReply': true, // 标记为自动回复
          }
        }),
        extension: '',
        description: '好友关系异常提醒',
      );
      
      // 发送消息给对方
      await OpenIM.iMManager.messageManager.sendMessage(
        message: notificationMessage,
        userID: targetUserID,
        groupID: null,
        offlinePushInfo: OfflinePushInfo(
          title: '系统通知',
          desc: '你已被对方删除，无法发送消息',
        ),
      );
      
      Logger.print('已向用户 $targetUserID 发送好友关系异常提醒');
    } catch (e) {
      Logger.print('发送好友关系异常提醒失败: $e');
    }
  }

  // 正常处理消息的逻辑
  void _processNormalMessage(Message msg) {
    // 处理通话相关的自定义消息
    if (msg.isCustomType) {
      try {
        final data = msg.customElem!.data;
        if (data != null) {
          final map = jsonDecode(data);
          final customType = map['customType'];
          if (customType == CustomMessageType.callingInvite ||
              customType == CustomMessageType.callingAccept ||
              customType == CustomMessageType.callingReject ||
              customType == CustomMessageType.callingCancel ||
              customType == CustomMessageType.callingHungup) {
            imLogic.processCallMessage(msg);
            return;
          }
        }
      } catch (e) {
        Logger.print('处理通话消息失败: $e');
      }
    }
    
    initLogic.showNotification(msg);
    onRecvNewMessage?.call(msg);
  }

  void recvOfflineMessage(Message msg) {
    // 处理离线通话相关的自定义消息
    if (msg.isCustomType) {
      try {
        final data = msg.customElem!.data;
        if (data != null) {
          final map = jsonDecode(data);
          final customType = map['customType'];
          if (customType == CustomMessageType.callingInvite ||
              customType == CustomMessageType.callingAccept ||
              customType == CustomMessageType.callingReject ||
              customType == CustomMessageType.callingCancel ||
              customType == CustomMessageType.callingHungup) {
            imLogic.processCallMessage(msg);
            return;
          }
        }
      } catch (e) {
        Logger.print('处理离线通话消息失败: $e');
      }
    }
    
    initLogic.showNotification(msg);
    onRecvOfflineMessage?.call(msg);
  }

  void recvCustomBusinessMessage(String s) {}

  void progressCallback(String msgId, int progress) {
    onMsgSendProgress?.call(msgId, progress);
  }

  void blacklistAdded(BlacklistInfo u) {
    onBlacklistAdd?.call(u);
  }

  void blacklistDeleted(BlacklistInfo u) {
    onBlacklistDeleted?.call(u);
  }

  void friendApplicationAccepted(FriendApplicationInfo u) {
    friendApplicationChangedSubject.addSafely(u);
  }

  void friendApplicationAdded(FriendApplicationInfo u) {
    friendApplicationChangedSubject.addSafely(u);
  }

  void friendApplicationDeleted(FriendApplicationInfo u) {
    friendApplicationChangedSubject.addSafely(u);
  }

  void friendApplicationRejected(FriendApplicationInfo u) {
    friendApplicationChangedSubject.addSafely(u);
  }

  void friendInfoChanged(FriendInfo u) {
    friendInfoChangedSubject.addSafely(u);
  }

  void friendAdded(FriendInfo u) {
    friendAddSubject.addSafely(u);
  }

  void friendDeleted(FriendInfo u) {
    friendDelSubject.addSafely(u);
  }

  void conversationChanged(List<ConversationInfo> list) {
    // 过滤掉非好友的单聊会话
    _filterNonFriendConversationsForChanged(list);
  }

  // 过滤非好友会话（用于会话变更）
  void _filterNonFriendConversationsForChanged(List<ConversationInfo> list) async {
    final filteredList = <ConversationInfo>[];
    
    for (final conversation in list) {
      // 只检查单聊会话，群聊会话不需要检查
      if (conversation.conversationType == ConversationType.single) {
        try {
          // 获取好友信息来验证是否为好友
          final friendsInfo = await OpenIM.iMManager.friendshipManager.getFriendsInfo(
            userIDList: [conversation.userID!],
          );
          
          // 如果是好友，则添加到过滤后的列表中
          if (friendsInfo.isNotEmpty) {
            Logger.print('允许更新好友会话: ${conversation.userID}');
            filteredList.add(conversation);
          } else {
            Logger.print('拒绝更新陌生人会话: ${conversation.userID}');
          }
        } catch (e) {
          // 如果获取好友信息失败，也拒绝更新会话
          Logger.print('获取好友信息失败，拒绝更新会话: ${conversation.userID}, error: $e');
        }
      } else {
        // 群聊会话直接添加
        filteredList.add(conversation);
      }
    }
    
    // 只有过滤后的会话才会被更新到消息列表中
    if (filteredList.isNotEmpty) {
      conversationChangedSubject.addSafely(filteredList);
    }
  }

  void newConversation(List<ConversationInfo> list) {
    // 过滤掉非好友的单聊会话
    _filterNonFriendConversations(list);
  }

  // 过滤非好友会话
  void _filterNonFriendConversations(List<ConversationInfo> list) async {
    final filteredList = <ConversationInfo>[];
    
    for (final conversation in list) {
      // 只检查单聊会话，群聊会话不需要检查
      if (conversation.conversationType == ConversationType.single) {
        try {
          // 获取好友信息来验证是否为好友
          final friendsInfo = await OpenIM.iMManager.friendshipManager.getFriendsInfo(
            userIDList: [conversation.userID!],
          );
          
          // 如果是好友，则添加到过滤后的列表中
          if (friendsInfo.isNotEmpty) {
            Logger.print('允许创建好友会话: ${conversation.userID}');
            filteredList.add(conversation);
          } else {
            Logger.print('拒绝创建陌生人会话: ${conversation.userID}');
          }
        } catch (e) {
          // 如果获取好友信息失败，也拒绝创建会话
          Logger.print('获取好友信息失败，拒绝创建会话: ${conversation.userID}, error: $e');
        }
      } else {
        // 群聊会话直接添加
        filteredList.add(conversation);
      }
    }
    
    // 只有过滤后的会话才会被添加到消息列表中
    if (filteredList.isNotEmpty) {
      conversationAddedSubject.addSafely(filteredList);
    }
  }

  void groupApplicationAccepted(GroupApplicationInfo info) {
    groupApplicationChangedSubject.add(info);
  }

  void groupApplicationAdded(GroupApplicationInfo info) {
    groupApplicationChangedSubject.add(info);
  }

  void groupApplicationDeleted(GroupApplicationInfo info) {
    groupApplicationChangedSubject.add(info);
  }

  void groupApplicationRejected(GroupApplicationInfo info) {
    groupApplicationChangedSubject.add(info);
  }

  void groupInfoChanged(GroupInfo info) {
    groupInfoUpdatedSubject.addSafely(info);
  }

  void groupMemberAdded(GroupMembersInfo info) {
    memberAddedSubject.add(info);
  }

  void groupMemberDeleted(GroupMembersInfo info) {
    memberDeletedSubject.add(info);
  }

  void groupMemberInfoChanged(GroupMembersInfo info) {
    memberInfoChangedSubject.add(info);
  }

  void joinedGroupAdded(GroupInfo info) {
    joinedGroupAddedSubject.add(info);
  }

  void joinedGroupDeleted(GroupInfo info) {
    joinedGroupDeletedSubject.add(info);
  }

  void totalUnreadMsgCountChanged(int count) {
    initLogic.showBadge(count);
    unreadMsgCountEventSubject.addSafely(count);
  }

  void inputStateChanged(InputStatusChangedData status) {
    inputStateChangedSubject.addSafely(status);
  }

  /// 处理自动回复的好友删除消息
  Future<void> _handleAutoReplyDeletedMessage(Message msg) async {
    try {
      // 查找对应的原始消息并标记为发送失败
      final chatLogic = Get.find<ChatLogic>(tag: GetTags.chat);
      // 遍历消息列表，找到最近发送的消息并标记为失败
      final messages = chatLogic.messageList;
      for (int i = messages.length - 1; i >= 0; i--) {
        final message = messages[i];
        Logger.print('检查消息 $i: 发送者=${message.sendID}, 状态=${message.status}, 时间=${message.sendTime}');
        if (message.sendID == OpenIM.iMManager.userID && 
            message.status != MessageStatus.failed &&
            (message.sendTime ?? 0) >= ((msg.sendTime ?? 0) - 5000)) { // 5秒内的消息
          Logger.print('找到匹配消息，标记为失败: ${message.clientMsgID}');
          Logger.print('消息状态修改前: ${message.status}');
          // 标记消息为发送失败
          message.status = MessageStatus.failed;
          Logger.print('消息状态修改后: ${message.status}');
          // 通知发送状态更新
          chatLogic.sendStatusSub.addSafely(MsgStreamEv<bool>(
            id: message.clientMsgID!,
            value: false,
          ));
          // 创建好友关系异常提示消息
          final hintMessage = await _createFriendshipFailureHint(msg.recvID!, msg.sendTime ?? 0);
          chatLogic.messageList.add(hintMessage);
          // 强制刷新消息列表
          chatLogic.messageList.refresh();
          // 刷新UI
          chatLogic.update();
          
          Logger.print('UI已刷新，消息状态应为失败');
          break;
        }
      }
    } catch (e) {
      Logger.print('处理自动回复消息失败: $e');
    }
  }
  
  /// 创建好友关系异常的失败提示消息
  Future<Message> _createFriendshipFailureHint(String userID, int timestamp) async {
    final message = await OpenIM.iMManager.messageManager.createFailedHintMessage(
      type: CustomMessageType.deletedByFriend,
    );
    
    // 设置消息的基本属性
    message.recvID = userID;
    message.sendTime = timestamp + 1;
    message.createTime = timestamp + 1;
    message.status = MessageStatus.succeeded;
    message.isRead = true;
    
    return message;
  }

  /// 检查是否为自动回复的好友删除消息
  bool _isAutoReplyDeletedMessage(Message msg) {
    if (!msg.isCustomType) return false;
    
    try {
      final data = msg.customElem?.data;
      if (data == null) return false;
      
      final map = jsonDecode(data);
      return map['customType'] == CustomMessageType.deletedByFriend &&
             map['data']?['isAutoReply'] == true;
    } catch (e) {
      Logger.print('检查自动回复消息失败: $e');
      return false;
    }
  }

  /// 检查是否为自动回复的通话拦截消息
  bool _isAutoReplyCallBlockedMessage(Message msg) {
    if (!msg.isCustomType) return false;
    
    try {
      final data = msg.customElem?.data;
      if (data == null) return false;
      
      final map = jsonDecode(data);
      return map['customType'] == CustomMessageType.deletedByFriend &&
             map['data']?['isAutoReply'] == true &&
             map['data']?['tips']?.contains('无法通话') == true;
    } catch (e) {
      Logger.print('检查自动回复通话拦截消息失败: $e');
      return false;
    }
  }

  /// 处理自动回复的通话拦截消息
  void _handleAutoReplyCallBlockedMessage(Message message) {
    try {
      // 通知通话控制器关闭通话页面
      final imController = Get.find<IMController>();
      imController.closeCallPageOnAutoReply();
      
      // 显示提示信息
      IMViews.showToast('对方不是您的好友，无法通话');
    } catch (e) {
      Logger.print('处理自动回复通话拦截消息失败: $e');
    }
  }
  
  void close() {
    initializedSubject.close();
    friendApplicationChangedSubject.close();
    friendAddSubject.close();
    friendDelSubject.close();
    friendInfoChangedSubject.close();
    selfInfoUpdatedSubject.close();
    groupInfoUpdatedSubject.close();
    conversationAddedSubject.close();
    conversationChangedSubject.close();
    memberAddedSubject.close();
    memberDeletedSubject.close();
    memberInfoChangedSubject.close();
    onKickedOfflineSubject.close();
    groupApplicationChangedSubject.close();
    imSdkStatusSubject.close();
    imSdkStatusPublishSubject.close();
    joinedGroupDeletedSubject.close();
    joinedGroupAddedSubject.close();
  }
}
